namespace _2 {

class ListNode<T> {
    constructor(public val: T, public next?: ListNode<T>) {}
    static ofArray(xs: number[]) {
        return xs.reduceRight((next: ListNode<number>, val: number) => new ListNode<number>(val, next), null)
    }

    static toArray(head: ListNode<number>): number[] {
        var result: number[] = new Array();
        var i = 0;
        while(!!head) {
            result[i] = head.val;
            head = head.next;
            i++;
        }
        return result;
    }
}

var addTwoNumbers = function(l1: ListNode<number>, l2: ListNode<number>): ListNode<number> {
    var x = 0;
    var head: ListNode<number> = null;
    var tail: ListNode<number> = null;
    while (l1 !== null || l2 !== null) {
        if (l1 !== null) { 
            x += l1.val
            l1 = l1.next
        }
        if (l2 !== null) { 
            x += l2.val
            l2 = l2.next
        }
        if (tail === null) {
            tail = new ListNode(x % 10)
            head = tail
        }
        else {
            tail.next = new ListNode(x % 10)
            tail = tail.next
        }
        
        x = Math.floor(x / 10) 
    }
    if (x > 0) {
        tail.next = new ListNode(x)
        tail = tail.next
    }
    return head;
};

console.assert( 
    ListNode.toArray( 
        addTwoNumbers( 
            ListNode.ofArray([2,4,3]),  
            ListNode.ofArray([5,6,4])
        )
    ).join('') === "708" 
)

console.assert( 
    ListNode.toArray( 
        addTwoNumbers( 
            ListNode.ofArray([5]),  
            ListNode.ofArray([5])
        )
    ).join('') === "01" 
)

console.log('The End')

}